package cn.zlb.frame.domain.pay.service.impl;

import cn.zlb.frame.common.event.EvenPublisher;
import cn.zlb.frame.common.exception.BizException;
import cn.zlb.frame.common.result.Result;
import cn.zlb.frame.domain.pay.model.PayAggregateRoot;
import cn.zlb.frame.domain.pay.model.entity.PaymentEntity;
import cn.zlb.frame.domain.pay.model.entity.ProductEntity;
import cn.zlb.frame.domain.pay.event.PayResultEvent;
import cn.zlb.frame.domain.pay.respository.gateway.IPayGateway;
import cn.zlb.frame.domain.pay.respository.gateway.IProductGateway;
import cn.zlb.frame.domain.pay.respository.persistence.IPayRepository;
import cn.zlb.frame.domain.pay.service.IPayDomainService;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.UUID;

/**
 * @author yangjie.deng@resico.cn
 * @date 2023-11-09 14:06:41
 * @describe class responsibility
 */
@Slf4j
@Service
public class PayDomainServiceImpl implements IPayDomainService {

    private static final String PAY_NOTICE_TOPIC = "shutdown_payment_delay_topic";

    @Resource
    private IProductGateway productGateway;

    @Resource
    private IPayRepository payRepository;

    @Resource
    private IPayGateway payGateway;

    @Resource
    private EvenPublisher evenPublisher;

    @Override
    public PaymentEntity pay(PayAggregateRoot aggregateRoot) {
        log.info("订单号: {} 发起支付.", aggregateRoot.getOrderNo());
        final ProductEntity productEntity = aggregateRoot.getProductEntity();

        // 调用商品服务, 获取库存信息
        final ProductEntity product = productGateway.findProductByNo(productEntity.getTenantNo(), productEntity.getProductNo());
        // 校验库存是否足够
        product.hasInventory(productEntity.getInventory());

        // 调用商品服务, 库存扣减
        final Result<Boolean> abatementResult = productGateway.inventoryAbatement(aggregateRoot.getProductEntity());
        if (!abatementResult.getData()) {
            throw new BizException(93000, "库存扣减失败.");
        }

        // 获取支付时所需要的信息, 如微信需要: 商户ID, 微信唯一标识, 认证手机号等信息
        final PaymentEntity baseEntity = payRepository.findThirdPayRequireInfo(aggregateRoot.getPaymentEntity());

        // 保存支付信息
        final PaymentEntity payment = payRepository.save(baseEntity);

        // 调用第三方服务, 进行支付
        payGateway.callPay(payment);

        // 发送支付事件, 延迟关单, 延迟20分钟
        final PayResultEvent event = new PayResultEvent();
        event.setPaymentNo(payment.getPaymentNo());
        event.setEventUniqueNo(UUID.randomUUID().toString());
        event.setDelayLevel(14);
        evenPublisher.sendDelay(PAY_NOTICE_TOPIC, event);

        log.info("订单号: {} 支付处理完成.", aggregateRoot.getOrderNo());
        return payment;
    }
}
